<?php

namespace plugin\voice\app\modelHandler;

use Throwable;
use Webman\Medoo\Medoo as db;

class Field2 extends Base
{
    protected $isUserApikey = false;

    protected $request;
    protected $useAzure = false;

    public function __construct($request = null){
        $modelField      = strtolower(substr(strrchr(get_class($this), '\\'), 1));
        $modelInfo       = db::get('voice_models','*',['field' => $modelField]);
        $this->getApi    = explode('://', $modelInfo['api_host'], 2);
        $this->getKey    = $this->getApiKeyFromDb($modelInfo['id']);
    }

    public function buildData($data){
        [$model, $messages, $temperature, $stream] = $data;
        $path             = $this->path;
        [$schema, $host]  = $this->getApi;
        $apiKey           = $this->getKey;
        $data = [
            'model'       => $model,
            'temperature' => $temperature,
            'stream'      => (bool)$stream,
            'messages'    => $messages,
        ];
        // gpt-4-vision 默认的max_tokens很低，这里需要前端传递
        if (strpos($model, 'gpt-4-vision') === 0) {
            $data['max_tokens'] = $this->request->post('max_tokens', 2000);
        }
        $body             = json_encode($data);
        $bodyLength       = strlen($body);
        $authorization    = "Authorization: Bearer $apiKey\r\n";
        return "POST $path HTTP/1.1\r\n" .
            "Host: $host\r\n" .
            "Connection: close\r\n" .
            "Content-Type: application/json\r\n" .
            $authorization .
            "Accept: text/event-stream\r\n" .
            "Content-Length: $bodyLength\r\n\r\n" .
            $body;
    }

    public function formatResponse($buffer){
        if ($buffer && $buffer[0] === '{') {
            if (!$this->isUserApikey) {
                $this->checkApiKeyAvailable($buffer);
            }
            return $buffer;
        }
        $chunks = explode("\n", $buffer);
        $content = '';
        foreach ($chunks as $chunk) {
            if ($chunk === "") {
                continue;
            }
            $chunk = trim(substr($chunk, 6));
            if ($chunk === "" || $chunk === "[DONE]") {
                continue;
            }
            try {
                $data = json_decode($chunk, true);
                if (isset($data['error'])) {
                    $content .= $data['error']['message'] ?? "";
                } else {
                    $content .= $data['choices'][0]['delta']['content'] ?? "";
                }
            } catch (Throwable $e) {
                echo $e;
            }
        }
        return $content;
    }

    public function getApiKeyFromDb($modelId = '1'){
        try {
            $key = db::get('voice_model_keys','api_key',['status' => 1, 'model_id' => $modelId,'ORDER' => ['update_time' => 'ASC']]);
            return $key ?: '';
        } catch (Throwable $exception) {}
        return '';
    }

    /**
     * 通过关键字检测apikey是否可用
     *
     * @param $errorMessage
     * @return void
     */
    protected function checkApiKeyAvailable($errorMessage){
        if (!strpos($errorMessage, 'error')) {
            return;
        }
        // 账号被禁用关键字
        $unavailableKeyWords = ['account_deactivated', 'billing_not_active', 'invalid_api_key', 'insufficient_quota'];
        $disabled = false;
        foreach($unavailableKeyWords as $word) {
            if (strpos($errorMessage, $word) !== false) {
                $disabled = true;
                break;
            }
        }
        // 查找apikey的记录
        $updateData = [];
        $keyInfo    = db::get('voice_model_keys','*',['api_key' => $this->apikey]);
        if ($keyInfo) {
            if ($disabled) {
                $updateData['status'] = 2;
            }
            $updateData['last_error'] = $errorMessage;
            $updateData['error_ime']  = date('Y-m-d H:i:s',time());
            db::update('voice_model_keys',$updateData,['id' => $keyInfo['id']]);
        }
    }

}